package cn.com.open.opensaas.scoreservice.logic;

import cn.com.open.opensaas.baiscommon.common.QuestionConstant;
import cn.com.open.opensaas.baiscommon.model.question.AnswerQuestionLog;
import cn.com.open.opensaas.baiscommon.model.question.QuestionContentJsonModel;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 判分工具类
 */
public class QuestionJudgeFactory {

    /**
     * 判分
     */
    public void judge(AnswerQuestionLog answerQuestionLog, Map<String, Object> resultMap){
        QuestionContentJsonModel answerQuestion = answerQuestionLog.getItems().get(0);
        Integer questionType = answerQuestion.getI3();
        switch (questionType) {
            case QuestionConstant.QUESTION_TYPE_RADIO://单选
                judgeRadio(answerQuestion,resultMap);
                break;
            case QuestionConstant.QUESTION_TYPE_CHECKBOX://多选
                judgeCheckbox(answerQuestionLog,resultMap);
                break;
            case QuestionConstant.QUESTION_TYPE_JUDGE://判断
                judgeRadio(answerQuestion, resultMap);
                break;
            case QuestionConstant.QUESTION_TYPE_GAP://填空
                if ( answerQuestion.getI32() == QuestionConstant.QUESTION_MOLD_OBJECTIVE) {//I32=0 客观题 判分  I32=1 主观题 不判分
                    judgeGap(answerQuestionLog,resultMap);
                }
                else{
                    resultMap.put(QuestionConstant.ITEM_IDENTIFIER, answerQuestion.getI1());
                    resultMap.put(QuestionConstant.STUDENT_ANSWER_SCORE, Double.valueOf(-1));
                    resultMap.put(QuestionConstant.SUB_ITEMS, answerQuestion.getSub());
                }
                break;
            case QuestionConstant.QUESTION_TYPE_MATCH://匹配
                judgeMatch(answerQuestionLog,resultMap);
                break;
            case QuestionConstant.QUESTION_TYPE_READ://阅读
                judgeMatch(answerQuestionLog, resultMap);
                break;
            case QuestionConstant.QUESTION_TYPE_CLOZE://完型
                judgeMatch(answerQuestionLog, resultMap);
                break;
            default:
                resultMap.put(QuestionConstant.ITEM_IDENTIFIER, answerQuestion.getI1());
                resultMap.put(QuestionConstant.STUDENT_ANSWER_SCORE, 0.0);
                resultMap.put(QuestionConstant.SUB_ITEMS,answerQuestion.getSub());
                break;
        }
    }

    /**
     * 匹配、阅读、完型 判分
     */
    private void judgeMatch(AnswerQuestionLog answerQuestionLog, Map<String, Object> resultMap) {
        QuestionContentJsonModel answerQuestion = answerQuestionLog.getItems().get(0);
        boolean isDecimal = answerQuestionLog.getIsDecimal();

        List<Map<String, Object>> subList = new ArrayList<>();//用于存储结果集中Sub的list
        //获取库中Question的Sub子列表
        List<QuestionContentJsonModel> dbQuestionSubList = answerQuestion.getSub();
        Double score = answerQuestion.getI9();
        //Integer score = Integer.valueOf(d.intValue());//所有子题总分
        BigDecimal totalScore = new BigDecimal(0);//用来统计整题所得分值

        for (Integer i = 0; i < dbQuestionSubList.size(); i++) {//循环库中Question的Sub子列表
            Map<String, Object> subMap = new HashMap<>();//用于存储每个子题的得分结果信息
            QuestionContentJsonModel dbQuestionSub = dbQuestionSubList.get(i);//循环中的每个子题
            if (equalList(dbQuestionSub.getI7(),dbQuestionSub.getI15())) {
                BigDecimal subScore = getScore(score, dbQuestionSubList.size(), 1.0, i, isDecimal);
                dbQuestionSub.setI16(formatDouble(subScore));
                totalScore = addSource(totalScore,subScore);
            } else {
                dbQuestionSub.setI16(0.0);
            }

            subMap.put(QuestionConstant.ITEM_IDENTIFIER, dbQuestionSub.getI1());
            subMap.put(QuestionConstant.STUDENT_ANSWER_SCORE, dbQuestionSub.getI16());
            subList.add(subMap);
        }
        answerQuestion.setI16(formatDouble(totalScore));

        getItemMap(answerQuestion.getI1(),answerQuestion.getI16(),subList,resultMap);
    }

    /**
     * 客观填空判分
     */
    private void judgeGap(AnswerQuestionLog answerQuestionLog, Map<String, Object> resultMap) {

        QuestionContentJsonModel answerQuestion = answerQuestionLog.getItems().get(0);
        boolean isDecimal = answerQuestionLog.getIsDecimal();
        //question I15答案   I9分数  dbQuestion I6答案   I7分数占比
        List<String> quesAnswerList = answerQuestion.getI15();//获取学生答案列表
        Double score = answerQuestion.getI9();
        //Integer score = dScore.intValue();//所有空总分数
        List<String> dbQuesAnswerList = answerQuestion.getI6(); //获取库中答案列表
        List<String> dbQuesScorePercentList = answerQuestion.getI7();//获取库中分值占比列表
        BigDecimal totalScore = new BigDecimal(0);//用于统计整题总分
        List<Double> fillScore = new ArrayList<>();
        if(dbQuesAnswerList != null && !dbQuesAnswerList.isEmpty()){
            //将每个空的分值默认为0
            for (int i = 0 ; i < dbQuesAnswerList.size(); i++) {
                fillScore.add(Double.valueOf(0));
            }

            if(quesAnswerList != null && !quesAnswerList.isEmpty()){
                int forLength = quesAnswerList.size();
                if(quesAnswerList.size() > dbQuesAnswerList.size()){
                    forLength = dbQuesAnswerList.size();
                }
                for (int i = 0; i < forLength; i++) {//循环学生答案列表
                    String quesAnswer = quesAnswerList.get(i);//循环中每个学生答案
                    String dbQuesAnswer = dbQuesAnswerList.get(i);//与学生答案相同索引的库中答案
                    String dbQuesScorePercent = dbQuesScorePercentList.get(i);//相应索引的分值占比
                    //I6-数组 答案
                    String[] answers = dbQuesAnswer.split(QuestionConstant.QUESTION_SEPARATOR);
                    //I7-数组 分值比
                    String[] scores = dbQuesScorePercent.split(QuestionConstant.QUESTION_SEPARATOR);
                    for (int j = 0; j < answers.length; j++) {
                        if (quesAnswer.equals(answers[j])) {
                            //获取客观填空题每个空的分值
                            BigDecimal eachEmptyScore = getScore(score, dbQuesAnswerList.size(), Double.parseDouble(scores[j]), i,isDecimal);
                            //展示每个空的得分
                            fillScore.set(i,formatDouble(eachEmptyScore));
                            //获取客观填空题总分
                            totalScore = addSource(totalScore,eachEmptyScore);
                        }
                    }
                }
            }
        }
        answerQuestion.setI16(formatDouble(totalScore));
        //每个空的得分
        answerQuestion.setFillScore(fillScore);

        resultMap.put(QuestionConstant.FILL_SCORE,fillScore);
        getItemMap(answerQuestion.getI1(),answerQuestion.getI16(),answerQuestion.getSub(),resultMap);
    }

    /**
     *  多选判分
     */
    private void judgeCheckbox(AnswerQuestionLog answerQuestionLog, Map<String, Object> resultMap) {
        QuestionContentJsonModel answerQuestion = answerQuestionLog.getItems().get(0);
        boolean isHalf = answerQuestionLog.getIsHalf();
        List<String> dbList = answerQuestion.getI7();
        List<String> list = answerQuestion.getI15();
        // isHalf: true 多选题将支持半对判分策略
        if(isHalf){
            //将业务分值转为Double类型
            Double totalScore = answerQuestion.getI9();

            if (equalList(dbList, list)) {//比较正确答案与学生答案是否一致
                answerQuestion.setI16(totalScore);//如果完成一致，得分
            } else {//不一致，半对分策略

                //只要有作答答案中存在正确答案不包含的的答案一律0分
                boolean iscontains = false;
                if(list.size() < dbList.size()){
                    for (String answer : list) {
                        iscontains = dbList.contains(answer);
                    }
                }
                if(iscontains){
                    answerQuestion.setI16(totalScore / 2);
                }else {
                    answerQuestion.setI16(0.0);
                }
            }

            getItemMap(answerQuestion.getI1(),answerQuestion.getI16(),answerQuestion.getSub(),resultMap);
        }else {
            judgeRadio(answerQuestion, resultMap);
        }
    }

    /**
     * 单选、多选、判断 判分
     * @param answerQuestion
     * @param resultMap
     */
    private void judgeRadio(QuestionContentJsonModel answerQuestion, Map<String, Object> resultMap) {
        //将业务分值转为Double类型
        Double totalScore = answerQuestion.getI9();
        if (equalList(answerQuestion.getI7(),answerQuestion.getI15())) {//比较正确答案与学生答案是否一致
            answerQuestion.setI16(totalScore);//如果完成一致，得分
        } else {//不一致，不得分
            answerQuestion.setI16(0.0);
        }
        getItemMap(answerQuestion.getI1(),answerQuestion.getI16(),answerQuestion.getSub(),resultMap);

    }



    /**
     * 拼接返回itemMap方法
     *
     * @param questionId
     * @param questionScore
     * @param subList
     * @param itemMap
     * @return 拼接返回map,{"I1":"","I16":"","Sub":[]}
     */
    public void getItemMap(Object questionId, Object questionScore, Object subList, Map<String, Object> itemMap) {
        itemMap.put(QuestionConstant.ITEM_IDENTIFIER, questionId);
        itemMap.put(QuestionConstant.STUDENT_ANSWER_SCORE, questionScore);
        itemMap.put(QuestionConstant.SUB_ITEMS, subList);
    }

    /**
     * 填空，完形，阅读获取分值方法
     *
     * @param score
     * @param subSize
     * @param scorePercent
     * @param index        当前索引，判断是否是最后一个
     * @param isDecimal
     * @return
     */
    public BigDecimal getScore(double score, Integer subSize, Double scorePercent, Integer index, boolean isDecimal) {
        //  true  客观填空，完形填空，阅读理解按double计算分值  false 按int计算
        if(isDecimal){
            // 四舍五入  保留一位小数
            BigDecimal sourceBigDecimal = new BigDecimal(score);
            BigDecimal subSizeBigDecimal = new BigDecimal(subSize);
            BigDecimal scorePercentBigDecimal = new BigDecimal(scorePercent);
            //平均分值  总分值/空的个数
            BigDecimal averageSource = sourceBigDecimal.divide(subSizeBigDecimal);
            BigDecimal len = new BigDecimal(subSize -1);
            //最后一空分值 =  总分值 - 前面空分之总和
            BigDecimal lastSource = sourceBigDecimal.subtract(averageSource.multiply(len));

            if (index < subSize - 1) {//不是最后一题
                return  averageSource.multiply(scorePercentBigDecimal);
            } else {//最后一题，(总分值 - 前面分之总和)*百分比
                return  lastSource.multiply(scorePercentBigDecimal);
            }
        }else {

            Integer resultScore = 0;
            if (index < subSize - 1) {//不是最后一题，分值取整*百分比
                resultScore = (int) Math.floor(((score / subSize.doubleValue()) * scorePercent));//向下取整，直接舍弃小数部分
            } else {//最后一题，(分值取整+余数)*百分比
                resultScore = (int) Math.floor(((score / subSize.doubleValue() + score % subSize) * scorePercent));
            }
            return BigDecimal.valueOf(resultScore);
        }
    }

    /**
     * 四舍五入  保留一位小数
     */
    public double formatDouble(BigDecimal source){
        // 四舍五入  保留一位小数
        return source.setScale(1, RoundingMode.UP).doubleValue();
    }

    /**
     * double 值相加
     * @param currentSource
     * @param newSource
     * @return
     */
    public static BigDecimal addSource(BigDecimal currentSource,BigDecimal newSource){
        return currentSource.add(newSource);
    }

    /**
     * 判断学生答案与库中存储答案是否一致
     *
     * @param answerList   学生答案列表
     * @param dbAnswerList 库中存储答案列表
     * @return
     */
    public boolean equalList(List dbAnswerList, List answerList) {
        //比较学生答案列表与为库中存储答案列表答案数量是否相等，不等则视为错误
        if (answerList.size() != dbAnswerList.size())
            return false;
        //循环判断库中答案列表是否包含学生答案，有一个不包含，则视为错误
        for (Object answer : answerList) {
            if (!dbAnswerList.contains(answer))
                return false;
        }
        return true;
    }

}
